﻿using System;
using System.Collections.Generic;
using System.Linq;
using LingDong.IndexEntities.Dictionary;
using LingDong.IndexEntities.Document;
using LingDong.IndexReader;
using NLog;
using PanGu;

namespace LingDong.QueryCore
{
    public class Query
    {
        #region Public Members

        public static void Init()
        {
            if (initFlag)
                return;

            initFlag = true;
            logger = LogManager.GetCurrentClassLogger();
            logger.Debug("Query Init.");

            try
            {
                logger.Debug("PanGu Segment Init.");
                Segment.Init();

                logger.Debug("Index Init.");
                index = new Index();
            }
            catch (Exception ex)
            {
                logger.Error("Error in Query Init: {0}", ex.Message);
                throw;
            }
        }

        public static void UnInit()
        {
            if (index != null)
            {
                index.Dispose();
            }
        }

        public static List<QueryResultEntity> GetQueryResult(string query)
        {
            if (index == null)
            {
                throw new InvalidOperationException("Call Query.Init() before query.");
            }

            List<Dictionary<int, InvertedListEntity>> allInvertedList = new List<Dictionary<int, InvertedListEntity>>();
            List<string> words = new Segment().DoSegment(query).Select(info => info.Word).ToList();
            foreach (string word in words)
            {
                Dictionary<int, InvertedListEntity> dic = index.GetInvertedList(word);
                if (dic == null || dic.Count == 0)
                    continue;
                
                allInvertedList.Add(dic);
            }
            List<ParsedDocumentEntity> docList = Ranker.GetResultDocList(index, allInvertedList);

            List<QueryResultEntity> result = new List<QueryResultEntity>();
            foreach (ParsedDocumentEntity doc in docList)
            {
                QueryResultEntity entity = new QueryResultEntity(doc);
                entity.Abstract = AbstractExtractor.GetAbstract(doc, allInvertedList, words);
                result.Add(entity);
            }
            return result;
        }

        public static OriginalDocumentEnity GetOriginalDocument(int id)
        {
            return index.GetOriginalDocument(id);
        }

        #endregion


        #region Private Members

        private static Index index;
        private static Logger logger;
        private static bool initFlag = false;

        #endregion
    }
}
